/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package brigal.fastbackup.data.settings;

import brigal.fastbackup.data.Profile;
import brigal.fastbackup.gui.FastBackupApp;
import brigal.xml.XMLTools;
import brigal.xml.XPathRequester;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.jdesktop.application.Application;
import org.jdesktop.application.ResourceMap;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 *
 * @author brigal
 */
public class Settings {

    private Vector<Profile> profiles;
    // <editor-fold defaultstate="collapsed" desc="Singleton pattern implementation">
    private static Settings instance;

    public static synchronized Settings getInstance() {
        if (instance == null) {
            instance = new Settings();
        }
        return instance;
    }

//    private Settings() {
    private Settings() {
        this.profiles = new Vector<Profile>();
        ;
    }
    // </editor-fold>

    public Vector<Profile> getProfiles() {
        return this.profiles;
    }

    public void setProfiles(Vector<Profile> profiles) {
        this.profiles = profiles;
    }

    public Document toXMLDocument() {
        Document doc = null;
        try {
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            doc = db.newDocument();

            this.appendXML(doc, doc);
        } catch (ParserConfigurationException ex) {
            Logger.getLogger(Settings.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            return doc;
        }
    }

    public void appendXML(Document appendToThisDocument, Node startingFromThisNode) {
        ResourceMap resourceMap = Application.getInstance(FastBackupApp.class).getContext().getResourceMap(FastBackupApp.class);
        String appName = resourceMap.getString("Application.name");
        String appVersion = resourceMap.getString("Application.version");

        // <Settings ApplicationName=... ApplicationVersion=...>
        Element eltSettings = appendToThisDocument.createElement("Settings");
        startingFromThisNode.appendChild(eltSettings);
        Node attrApplication = appendToThisDocument.createAttribute("ApplicationName");
        attrApplication.setNodeValue(appName);
        eltSettings.getAttributes().setNamedItem(attrApplication);
        Node attrVersion = appendToThisDocument.createAttribute("ApplicationVersion");
        attrVersion.setNodeValue(appVersion);
        eltSettings.getAttributes().setNamedItem(attrVersion);
        // <Profiles>
        Element eltProfiles = appendToThisDocument.createElement("Profiles");
        eltSettings.appendChild(eltProfiles);
        for (Profile profile : this.profiles) {
            profile.appendXML(appendToThisDocument, eltProfiles);
        }
    }

    public String toXMLString() {
        return XMLTools.toXMLString(this.toXMLDocument());
    }

    public void fromXML(String xmlData) {
        this.profiles = new Vector<Profile>();
        XPathRequester xpr = new XPathRequester(xmlData);

        NodeList profileList = xpr.selectNodes("/Settings/Profiles/Profile");
        for (int i = 0; i <
                profileList.getLength(); i++) {
            Node profile = profileList.item(i);
            xpr.setNode(profile);
            String name = xpr.selectSingleNodeText("./@Name");
            String source = xpr.selectSingleNodeText("./Source");
            String destination = xpr.selectSingleNodeText("./Destination");
            this.profiles.add(new Profile(name, source, destination));
        }

    }

    @Override
    public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }

        if (anObject instanceof Settings) {
            Settings otherSettings = (Settings) anObject;
            if (this.profiles.size() != otherSettings.profiles.size()) {
                return false;
            }

            for (int i = 0; i <
                    this.profiles.size(); i++) {
                if (!this.profiles.get(i).equals(otherSettings.profiles.get(i))) {
                    return false;
                }

            }
            return true;
        }

        return false;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash =
                53 * hash + (this.profiles != null ? this.profiles.hashCode() : 0);
        return hash;
    }
}
